/* dot11Lib.h - Contains the main definitions for the 802.11 Framework.  */

/* Copyright 2004 Wind River Systems, Inc. */

/* 
Modification History
--------------------
03u,09sep05,rb  Added countryCode as boot parameter
03t,25aug05,rb  Added 11d info to channel structure
03t,30aug05,rb  Removed EIOCSUNICASTKEYNUM and related
03s,19aug05,rb  Added Turbo support
03r,19aug05,rb  Increased timeout time for Windows stations
03q,04aug04,rb  Moved DOT11_CHANNEL_LIST to dot11UsrLib.h
03p,04aug05,rb  Increase default passive scan time to be greater than default
                 beacon interval
03o,03aug05,rb  Implemented user authentication callback
03n,28jul05,rb  Added hdd->calTime
03m,28jul05,rb  Added hdd->calTimer
03l,25jul05,rb  Removed pAp->pmCount
03k,20jul05,rb  Fix #warning
03j,14jul05,rb  Implemented KSL memory pool, moved lastSeq into pDot11
03i,14jul05,rb  Move pmState to SME_OBJ to alllow DOT11_MODE_NONE config
03h,10jun05,rb  Added RSN passphrase caching and 4way timer
03g,18may05,rb  Fix for bug B0367 - TSN does not work on Sta
03f,28apr05,rb  Added _BIT definition to dot11UsrLib.h; Moved encryption types
                 to usrLib
03e,25apr05,rb  Moved definitions needed for IOCTLs from dot11Lib.h to
                 dot11UsrLib.h
03d,22apr05,rb  Added authentication callback wrapper
03c,15apr05,rb  Corrected 4-way retry time to value specified by standard
03b,14apr05,rb  Added support fr Transmit Power Scaling (WIOCSTXPOWERSCALE)
03a,06apr05,rb  Fix for SPR 107235: data path does not handle non-ethernet
                 packets correctly
02z,09mar05,rb  Change prototype of pDot11->sme->ksl.show
02y,09mar05,rb  Added hdd->hwVersionGet
02x,08mar05,rb  Added dtimPacketFlush() to HDD_OBJ
02w,03mar05,rb  Security code review changes
02v,01mar05,rb  Modified definition of WIOCSDOT1XPORTSTATUS and
                 WIOCSAUTHCALLBACK
02u,16feb05,rb  Renumbered IOCTLs to work with RTP management
02t,11feb05,rb  Increased timeout
02s,11feb05,rb  Adjusted EAPOL-timeout
02r,04feb05,rb  Added B/G compatibility mode
02q,02feb05,rb  Resolved vxWorks 6.0 compatability issue (cioTimer.h)
02p,26jan05,rb  Implemented SKA
02o,25jan05,rb  Made security components optionally buildable
02n,21jan05,rb  Added hdd->countryCodeChange() and hdd->macAddrChange()
02m,21jan05,rb  Removed some dead IOCTLs
02l,20jan05,rb  Added new security stats, MIC ctrmsrs
02k,17jan05,rb  Revised DOT11_SCAN_REQ structure
02j,06jan05,rb  Added decrypt & MIC error counters, MIC countermeasures
02i,05jan05,rb  Fix for SPR 103854 - Need to update reference in TXD to use
                 MBlks
02h,04jan05,rb  Added gtkRecalc member to RSN_OBJ
02g,23dec04,rb  Memory footprint reduction
02f,21dec04,rb  Added WPA2/802.11i support
02e,01nov04,rb  Added security policy parameters
02d,27oct04,rb  Added WEP Key Mapping Support
02c,03oct04,rb  Changes from dot11SmeApLib.c and dot11SmeIbssLib.c code review
02b,26aug04,rb  Fix for SPR 101351 : Supplicant does not work on LE
                 architectures.
02a,25aug04,rb  Wind River Wireless Ethernet Driver 2.0 FCS
*/

#ifndef __INCdot11Libh
#define __INCdot11Libh
#ifdef  __cplusplus
extern "C" {
#endif /* __cplusplus */

#include <vxWorks.h>
#include <end.h>
#include <muxLib.h>
#include <wdLib.h>
#include <logLib.h>
#include <taskLib.h>
#include <msgQLib.h>
#include "dot11UsrLib.h"

/************************************************************************
*         USER MODIFIABLE PARAMETERS
************************************************************************/

/* Memory initialization constants */
#define DOT11_NUMCL                     256
#define DOT11_NUMCLBLK                  DOT11_NUMCL
#define DOT11_NUMMBLK                   DOT11_NUMCL * 2

/*
* DOT11_FOURWAY_MSG_TIMEOUT - specified the amount of time the RSN libraries
*       will wait for a response to an EAPOL-KEY message before assuming the 
*       message is lost and retrying
*/
#define DOT11_FOURWAY_MSG_TIMEOUT         (sysClkRateGet() / 2) /* 500 ms */

/*
* DOT11_FOURWAY_GLOBAL_TIMEOUT - specified the amount of time the RSN libraries
*       will wait for the fourway handshake to complete before resetting the
*       connection.
*/
#define DOT11_FOURWAY_GLOBAL_TIMEOUT      (sysClkRateGet() * 3 / 2) /* 1500 ms */

/*
* DOT11_FOURWAY_8021X_TIMEOUT - specified the amount of time the RSN libraries
*       will wait for the 802.1X auth to finish and the fourway handshake to 
*       commence  before resetting the connection.
*/
#define DOT11_FOURWAY_8021X_TIMEOUT      (sysClkRateGet() * 20) /* 20 sec */

/*
* DOT11_FOURWAY_TIMEOUT_MAX - Maximum number of times that the RSN libraries
*       will resent an EAPOL-KEY message before assuming that there is an
*       error and giving up.
*/
#define DOT11_FOURWAY_TIMEOUT_MAX        5


/*
* DOT11_FRAGMENT_TIMEOUT_TICKS - The maximum delay between fragments, in
*       ticks of the kernel clock.  Since the kernel clock is really
*       coarse, pretty much any value is reasonable - fragments should not
*       be delayed by much time at all.
*/
#define DOT11_FRAGMENT_TIMEOUT_TICKS     10

/*
* DOT11_KSL_POOL_SIZE - The number of entries in the KSL pool.  This represents
*       an upper limit on the number of stations or APs that the device can
*       keep track of.  This number should be increased for a device that
*       will be operated in an extremely busy environment 
*/
#define DOT11_KSL_POOL_SIZE              64

/*
* DOT11_KSL_CLEANUP_TIME - The time between cleanups of the KSL.  Every 
*       DOT11_KSL_CLEANUP_TIME seconds, the KSL cleanup task runs, to check
*       for any stale/inactive KSL entries and return them to the free pool.  
*/
#define DOT11_KSL_CLEANUP_TIME     (sysClkRateGet() * 60 * 2) /* 2 min */
/*
* DOT11_KSL_MAX_AGE - This is the amount of time a station can be inactive for
*       before the KSL considers it to be "inactive".  Entries with an 
*       inactivity time older than this value are eligible for deletion next
*       time the KSL cleanup task runs.
*/
#define DOT11_KSL_MAX_AGE          (sysClkRateGet() * 60 * 5) /* 5 min */


/************************************************************************
*         CONSTANT PARAMETERS - Do not change anything below this point
************************************************************************/

/* Forward declaration of DOT11_FW so the objects below can use it */
typedef struct dot11Framework DOT11_FW;

/* Include the slave header files */

#include "drv/wlan/dot11SmeIbssLib.h"
#include "drv/wlan/dot11SmeEssLib.h"
#include "drv/wlan/dot11SmeApLib.h"

typedef unsigned long long int DOT11_UINT64;

/* This is a really handy macro that we're going to need.  We'll define it if
it's not already defined */
#ifndef _BIT
#define _BIT(x) (1<<(x))
#endif


#define DOT11_MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"

#define DOT11_MAC_ADDR(x) (x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5]
#define DOT11_IS_MCAST(x)          (((x)[0] & 0x01) == 0x01)


/* These macros convert between native byte oder and the oder used by the PCI 
bus, Little Endian */
#if (_BYTE_ORDER == _BIG_ENDIAN)    
#define DOT11_LE_TO_CPU_16(x) (((x) >> 8) | (((x) & 0xff) << 8))
#define DOT11_CPU_TO_LE_16(x) (((x) >> 8) | (((x) & 0xff) << 8))
#define DOT11_LE_TO_CPU_32(x) LONGSWAP(x)
#define DOT11_CPU_TO_LE_32(x) LONGSWAP(x)

#define DOT11_BCOPY_LE_TO_CPU(src, dst, len) dot11BcopySwap(src,dst,len)

#else
#define DOT11_LE_TO_CPU_16(x) (x)
#define DOT11_CPU_TO_LE_16(x) (x)
#define DOT11_LE_TO_CPU_32(x) (x)
#define DOT11_CPU_TO_LE_32(x) (x)

#define DOT11_BCOPY_LE_TO_CPU(src, dst, len) bcopy(src,dst,len)
#endif

/*************************************************************************
*Debugging macros that control the debug levels
**************************************************************************/

/* ***  undefine this to get rid of all debugging in the driver.  This might
be desirable for production builds */
#define DOT11_DEBUG_GLOBAL
#ifdef DOT11_DEBUG_GLOBAL

/* Debug level definitions */
#define DOT11_DEBUG_ALL                 0  /* Always log message */
#define DOT11_DEBUG_FATAL               1  /* Non-recoverable error */
#define DOT11_DEBUG_ERROR               2  /* Recoverable error */
#define DOT11_DEBUG_INFO                3  /* Information message */
#define DOT11_DEBUG_FLOOD               4  /* Packet traces, info in a loop */
#define DOT11_DEBUG_NONE                99 /* Do not print any debug info */

/* Debug area definitions */
#define DOT11_AREA_ALL                  0  /* Don't use for macro */
#define DOT11_AREA_INIT                 1
#define DOT11_AREA_SME                  2
#define DOT11_AREA_DPE                  3
#define DOT11_AREA_HDD                  4
#define DOT11_AREA_INT                  5
#define DOT11_AREA_RSN                  6
#define DOT11_MAX_DEBUG_AREAS           7

IMPORT INT32 dot11DebugArray[DOT11_MAX_DEBUG_AREAS]; 

#define DOT11_LOG(level, area, message) \
    if ((level) <= dot11DebugArray[(area)]) logMsg message

/* DOT11_LOG_FLUSH is used after passing a string parameter to cause logLib
to execute immediately.  This should not be used on the critical path */
#define DOT11_LOG_FLUSH taskDelay(0)

/* DOT11_ASSERT() is no longer supported, but it is necessary to keep it in
for a while for backwards compatability */
#define DOT11_ASSERT(x) 

#else /* ! DOT11_DEBUG_GLOBAL */

#define DOT11_LOG(level, area, message)
#define DOT11_LOG_FLUSH
#define DOT11_ASSERT(x)
#endif /* DOT11_DEBUG_GLOBAL */



/* Channel flags */
#define DOT11_RADIO_UNKNOWN             -1

/* These modes are not currently implemented */
#define DOT11_RADIO_MAX                  0x20

/* The total number of the above modes that we support.  
It is used in ar52SuppRateGet() */
#define DOT11_RADIO_SUPP_MODES          3

#define DOT11_CHANNEL_INVALID           0

IMPORT const char * dot11ModeStr[];
IMPORT const char * dot11ModeNames[];
IMPORT const char * dot11BcastMAC;
IMPORT const char * dot11NullMAC;
IMPORT const char * dot11EncryptNames[];
IMPORT const char * dot114wayStateNames[];
IMPORT const char * dot11SecPolNames[];
IMPORT const char * dot11AuthPolNames[];
IMPORT const char * dot11AuthTypeStr[];

/* Values for hdd.pmState */
#define DOT11_PMMODE_ACTIVE                 1
#define DOT11_PMMODE_POWERSAVE              2

#define DOT11_SNAP_HEADER_LEN           8

typedef struct 
{
    UINT16 snap;
    UINT16 control;   /* first byte contain actual control field */ 
    UINT16 orgCode;
    UINT16 protocol;
} _WRS_PACK_ALIGN(1) DOT11_LLC_HEADER;

#define DOT11_LLC_RFC1024               0x00F8
#define DOT11_LLC_8021H                 0x0000

#define DOT11_ETHER_HEADER_LEN          14
#define DOT11_FCS_SIZE                  4   /* Size of Frame Checksum field */

#define DOT11_MTU                       2304
#define DOT11_MAX_PACKET                2346
#define DOT11_ETHERMTU                  1500
#define DOT11_MAXRATE                   54

/* Fix for SPR 101351 - preswap DOT1X_ETHERTYPE, then swap it back for BE 
archs */
#define DOT1X_ETHERTYPE                 DOT11_CPU_TO_LE_16(0x8e88)

#define DOT1X_CALLBACK_ASSOC         (1) /* Callback called due to association*/
#define DOT1X_CALLBACK_DISASSOC      (2) /* Callback called due to disassociation*/

/* These definitions are used with WIOCSDOT1XPORTSTATE */
#define DOT11_DOT1XPORT_UNCONTROLLED    0
#define DOT11_DOT1XPORT_CLOSED          1
#define DOT11_DOT1XPORT_OPEN            2

/* The maximum association ID is limited by the fact that there are only 14
bits available in the field to use */
#define DOT11_MAX_AID                  ((1 << 14) - 1)  


/* The time that a STA waits for a response on each channel when doing an 
active scan */
#define DOT11_SCAN_ACTIVE_DWELL_TIME    ((sysClkRateGet() / 50) + 1) 

/* The time that a STA listens for beacons on each channel when doing a 
passive scan */
#define DOT11_SCAN_PASSIVE_DWELL_TIME   (sysClkRateGet() * 2 / 5)  /* 400 ms */

/* The beacon response time is the amount of time it takes the beacon to go
from the tranmitter to the beacon receive routine.  This time is measured in
 802.11 time units.  */
#define DOT11_BEACON_RESP_TIME          1

/* The default DTIM time is the default number of beacons between DTIMS */
#define DOT11_DEFAULT_DTIM_PERIOD       2

/* The following definitions control the behaviour of the transmit queue */
#define DOT11_TX_SEM_WAIT               30 /* ticks */
#define DOT11_TX_QUEUE_LIFETIME         90 /* ticks */

/* A magic number used to represent the "ANY" SSID */
#define DOT11_SSID_NONE                 ((char)-1)

/* The size of an OUI = 3 bytes */
#define DOT11_OUI_SIZE                  3

/* A macro to convert between timestamps and times in 802.11 timeunits 
 (1024 us).  This macro assumes the parameter is a DOT11_TIMESTAMP. */
#define DOT11_TSF_TO_TU(tsf) ((tsf.low >> 10) | (tsf.high << 22))
/***************************************************************************/
/*             IEEE 802.11 Header Information                              */
/***************************************************************************/

/* This is the header for a standard packet (no WDS).  What follows depends on
the specific type of the packet, as detailed in the frame control header */
typedef struct 
    {
    UINT16 frameCtrl;
    UINT16 duration;
    UINT8  addr1[DOT11_ADDR_LEN];
    UINT8  addr2[DOT11_ADDR_LEN];
    UINT8  addr3[DOT11_ADDR_LEN];
    UINT16 seqCtrl;
    } _WRS_PACK_ALIGN(1) DOT11_HEADER;

/* Fields in the Frame Control Header */
#define DOT11_FCTL_VERSION_MASK         0x0003
#define DOT11_FCTL_VERSION_SHIFT        _BIT(0)

#define DOT11_FCTL_TYPE_MASK            0x000C
#define DOT11_FCTL_TYPE_SHIFT           _BIT(2)

#define DOT11_FCTL_SUBTYPE_MASK         0x00F0
#define DOT11_FCTL_SUBTYPE_SHIFT        _BIT(4)

#define DOT11_FCTL_TO_DS                _BIT(8)
#define DOT11_FCTL_FROM_DS              _BIT(9)
#define DOT11_FCTL_MORE_FRAG            _BIT(10)
#define DOT11_FCTL_RETRY                _BIT(11)
#define DOT11_FCTL_PM                   _BIT(12)
#define DOT11_FCTL_MORE_DATA            _BIT(13)
#define DOT11_FCTL_WEP                  _BIT(14)
#define DOT11_FCTL_ORDER                _BIT(15)

/* Frame types */
#define DOT11_FTYPE_DATA                0x8
#define DOT11_FTYPE_MGMT                0x0
#define DOT11_FTYPE_CTRL                0x4

/* Frame subtypes */
#define DOT11_STYPE_ASSOC_REQ           0x00
#define DOT11_STYPE_ASSOC_RESP          0x10
#define DOT11_STYPE_REASSOC_REQ         0x20
#define DOT11_STYPE_REASSOC_RESP        0x30
#define DOT11_STYPE_PROBE_REQ           0x40
#define DOT11_STYPE_PROBE_RESP          0x50
#define DOT11_STYPE_BEACON              0x80
#define DOT11_STYPE_ATIM                0x90
#define DOT11_STYPE_DISASSOC            0xa0
#define DOT11_STYPE_AUTH                0xb0
#define DOT11_STYPE_DEAUTH              0xc0
#define DOT11_STYPE_PS_POLL             0xa0
#define DOT11_STYPE_RTS                 0xb0
#define DOT11_STYPE_CTS                 0xc0
#define DOT11_STYPE_ACK                 0xd0
#define DOT11_STYPE_DATA                0x00
#define DOT11_STYPE_DATA_NULL           0x40

/* The DOT11_FTYPE macro masks off the frame type and subtype portions of the
frame control header, which is passed in */
#define DOT11_FTYPE(frameCtrl) ((frameCtrl) & (DOT11_FCTL_TYPE_MASK | \
                                           DOT11_FCTL_SUBTYPE_MASK))
/* Merged subtypes and types used with DOT11_FTYPE macro */
#define DOT11_TYPE_ASSOC_REQ           0x00
#define DOT11_TYPE_ASSOC_RESP          0x10
#define DOT11_TYPE_REASSOC_REQ         0x20
#define DOT11_TYPE_REASSOC_RESP        0x30
#define DOT11_TYPE_PROBE_REQ           0x40
#define DOT11_TYPE_PROBE_RESP          0x50
#define DOT11_TYPE_BEACON              0x80
#define DOT11_TYPE_ATIM                0x90
#define DOT11_TYPE_DISASSOC            0xa0
#define DOT11_TYPE_AUTH                0xb0
#define DOT11_TYPE_DEAUTH              0xc0
#define DOT11_TYPE_PS_POLL             0xa4
#define DOT11_TYPE_RTS                 0xb4
#define DOT11_TYPE_CTS                 0xc4
#define DOT11_TYPE_ACK                 0xd4
#define DOT11_TYPE_DATA                0x08
#define DOT11_TYPE_DATA_NULL           0x48

/* The RX MAP is passed to the HDD as an array of 64 function pointers. */
#define DOT11_RX_MAP_NUM             64

/* This is a macro that gives an RX MAP index given the frame control header*/
#define DOT11_FCTL_TO_RXMAP_INDEX(x) (((x) & 0xfc) >> 2)

#define DOT11_RXMAP_ASSOC_REQ      DOT11_FCTL_TO_RXMAP_INDEX(0x00)
#define DOT11_RXMAP_ASSOC_RESP     DOT11_FCTL_TO_RXMAP_INDEX(0x10)
#define DOT11_RXMAP_REASSOC_REQ    DOT11_FCTL_TO_RXMAP_INDEX(0x20)
#define DOT11_RXMAP_REASSOC_RESP   DOT11_FCTL_TO_RXMAP_INDEX(0x30)
#define DOT11_RXMAP_PROBE_REQ      DOT11_FCTL_TO_RXMAP_INDEX(0x40)
#define DOT11_RXMAP_PROBE_RESP     DOT11_FCTL_TO_RXMAP_INDEX(0x50)
#define DOT11_RXMAP_BEACON         DOT11_FCTL_TO_RXMAP_INDEX(0x80)
#define DOT11_RXMAP_ATIM           DOT11_FCTL_TO_RXMAP_INDEX(0x90)
#define DOT11_RXMAP_DISASSOC       DOT11_FCTL_TO_RXMAP_INDEX(0xa0)
#define DOT11_RXMAP_AUTH           DOT11_FCTL_TO_RXMAP_INDEX(0xb0)
#define DOT11_RXMAP_DEAUTH         DOT11_FCTL_TO_RXMAP_INDEX(0xc0)
#define DOT11_RXMAP_PSPOLL         DOT11_FCTL_TO_RXMAP_INDEX(0xa4)
#define DOT11_RXMAP_RTS            DOT11_FCTL_TO_RXMAP_INDEX(0xb4)
#define DOT11_RXMAP_CTS            DOT11_FCTL_TO_RXMAP_INDEX(0xc4)
#define DOT11_RXMAP_ACK            DOT11_FCTL_TO_RXMAP_INDEX(0xd4)
#define DOT11_RXMAP_CFEND          DOT11_FCTL_TO_RXMAP_INDEX(0xe4)
#define DOT11_RXMAP_CFENDACK       DOT11_FCTL_TO_RXMAP_INDEX(0xf4)
#define DOT11_RXMAP_DATA           DOT11_FCTL_TO_RXMAP_INDEX(0x08)
#define DOT11_RXMAP_DATA_CFACK     DOT11_FCTL_TO_RXMAP_INDEX(0x18)
#define DOT11_RXMAP_DATA_CFPOLL    DOT11_FCTL_TO_RXMAP_INDEX(0x28)
#define DOT11_RXMAP_DATA_CFACKPOLL DOT11_FCTL_TO_RXMAP_INDEX(0x38)
#define DOT11_RXMAP_DATA_NULL      DOT11_FCTL_TO_RXMAP_INDEX(0x48)
#define DOT11_RXMAP_CF_ACK         DOT11_FCTL_TO_RXMAP_INDEX(0x58)
#define DOT11_RXMAP_CF_POLL        DOT11_FCTL_TO_RXMAP_INDEX(0x68)
#define DOT11_RXMAP_CF_ACK_POLL    DOT11_FCTL_TO_RXMAP_INDEX(0x78)




/* The mask to get fragment number from the seqctl field */
#define DOT11_SEQCTL_FRAGNUM           0x000f
#define DOT11_SEQCTL_SEQ               0xfff0

#define DOT11_WEP_IV_SIZE              4
#define DOT11_WEP_EXT_IV_SIZE          4
#define DOT11_EXT_IV                   _BIT(5)
#define DOT11_WEP_ICV_SIZE             4
#define DOT11_MIC_LEN                  8


typedef struct
    {
    UINT32 low;
    UINT32 high;
    } DOT11_TIMESTAMP;

typedef UINT16 DOT11_FCTL;
typedef UINT16 DOT11_DURATION;
typedef UINT16 DOT11_BEACON_RATE;
typedef UINT16 DOT11_LISTEN_INT;
typedef UINT16 DOT11_STATUS;
typedef UINT16 DOT11_AID;

/* Mask to get the AID out of the AID field - bits 14 and 15 are always set */
#define DOT11_AID_MASK                  0x3fff
#define DOT11_AID_MASK_POS              0xc000

/* These are definitions for the element IDs found in Information Element
fields in Management Frames as per 7.3.2 of IEEE 802.11(2003) */
#define DOT11_ELEMID_SSID               0
#define DOT11_ELEMID_SUPP_RATES         1
#define DOT11_ELEMID_FH_PARAM           2
#define DOT11_ELEMID_DS_PARAM           3
#define DOT11_ELEMID_CF_PARAM           4
#define DOT11_ELEMID_TIM                5
#define DOT11_ELEMID_IBSS               6
#define DOT11_ELEMID_COUNTRY            7
#define DOT11_ELEMID_HOP_PARAM          8
#define DOT11_ELEMID_HOP_TABLE          9
#define DOT11_ELEMID_REQUEST            10
#define DOT11_ELEMID_CHALLENGE          16
#define DOT11_ELEMID_CHALLENGE_EXT      17
#define DOT11_ELEMID_ERP                42
#define DOT11_ELEMID_RSN                48
#define DOT11_ELEMID_EXT_RATES          50
#define DOT11_ELEMID_WPA                221
#define DOT11_ELEMID_KDE                221 /* Yes - the same as WPA */

/* These are the possible STATUS codes that can be returned in an Auth 
or Assoc Rsp frame */
#define DOT11_STATUS_OK                 0
#define DOT11_STATUS_FAIL               1
#define DOT11_STATUS_CAP_UNSUPPORT      10
#define DOT11_STATUS_NO_ASSOC           11
#define DOT11_STATUS_ASSOC_DENIED       12
#define DOT11_STATUS_AUTH_UNSUPPORT     13
#define DOT11_STATUS_BAD_SEQ            14
#define DOT11_STATUS_CHAL_FAIL          15
#define DOT11_STATUS_TIMEOUT            16
#define DOT11_STATUS_NO_MORE_ASSOC      17 
#define DOT11_STATUS_RATE_UNSUPPORT     18

#define DOT11_STATUS_INVALID_IE         40
#define DOT11_STATUS_POLICY_REJECT      46


/* These are the possible reason codes that can be used in a deauth / disassoc*/
#define DOT11_REASON_UNSPECIFIED        1
#define DOT11_REASON_NO_LONGER_VALID    2
#define DOT11_REASON_DEAUTH_LEAVING     3
#define DOT11_REASON_INACTIVITY         4
#define DOT11_REASON_AP_FULL            5
#define DOT11_REASON_NOT_AUTH           6
#define DOT11_REASON_NOT_ASSOC          7
#define DOT11_REASON_DISASSOC_LEAVING   8
#define DOT11_REASON_ASSOC_NOT_AUTH     9
#define DOT11_REASON_MIC_FAILURE        14
#define DOT11_REASON_FOURWAY_TIMEOUT    15


#define DOT11_AUTH_CHAL_MAX        253
#define DOT11_AUTH_CHAL_SIZE       128

#define DOT11_IE_HEADER_SIZE       2 /* size of the length and elementId  */
#define DOT11_IE_MAX_SIZE          255

/**************************************************************************
*  DOT11_IE_GENERIC - A structure holding an information element of 
*                     indeterminate type
***************************************************************************/
typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    UINT8  data[DOT11_IE_MAX_SIZE];    /* Arbitary amount of data - use ptr once typed */
    } _WRS_PACK_ALIGN(1) DOT11_IE_GENERIC;


/**************************************************************************
*  DOT11_IE_SSID - A structure holding the SSID Information Element.  Note
*                  that the ssid field may be up to 32 bytes long.
***************************************************************************/
typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    char  ssid[DOT11_SSID_LEN];
    } _WRS_PACK_ALIGN(1) DOT11_IE_SSID;

/**************************************************************************
* DOT11_IE_CFP - PCF information element
***************************************************************************/
typedef struct
    {
    UINT8  elementId;
    UINT8  length;                          /* Should always be 6 */
    UINT8  cfpCount;
    UINT8  cfpPeriod;
    UINT16 cfpMaxDuration;                  /* Maximum duration of CFP */
    UINT16 cfpRemDuration;                  /* Duration left in current CFP */
    } _WRS_PACK_ALIGN(1) DOT11_IE_CFP;

/**************************************************************************
*  DOT11_IE_SUPP_RATES - The Supported Rates Information Element
***************************************************************************/
#define DOT11_IE_SUPP_RATES_MAX    8
#define DOT11_RATE_MAX             8

typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    UINT8  rates[DOT11_IE_SUPP_RATES_MAX];
    } _WRS_PACK_ALIGN(1) DOT11_IE_SUPP_RATES;

/**************************************************************************
*  DOT11_IE_CHAL_TEXT - Challenge text for shared key authentication
***************************************************************************/
typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    char  chalText[DOT11_AUTH_CHAL_MAX];
    } _WRS_PACK_ALIGN(1) DOT11_IE_CHAL_TEXT;


/**************************************************************************
*  DOT11_IE_EXT_RATES - The Extended Rates Information Element
***************************************************************************/
#define DOT11_IE_EXT_RATES_MAX    253
typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    UINT8  rates[DOT11_IE_EXT_RATES_MAX];
    } _WRS_PACK_ALIGN(1) DOT11_IE_EXT_RATES;

/**************************************************************************
*  DOT11_IE_TIM - Traffic Indication Message IE
***************************************************************************/
#define DOT11_MAX_PVB              251  /* Maximum size of Partial Virtual Bm*/
#define DOT11_TIM_TI               0x1  /* Traffic ind. bit in bmControl */
#define DOT11_TIM_MIN_LEN          4    /* Length of empty TIM */
#define DOT11_TIM_HDR_LEN          5    /* Length of  TIM header */
typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    UINT8 dtimCount;
    UINT8 dtimPeriod;
    UINT8 bitmapCtrl;
    UINT8 pvb[DOT11_MAX_PVB];
    } _WRS_PACK_ALIGN(1) DOT11_IE_TIM;

/**************************************************************************
*  DOT11_IE_IBSS - IBSS parameters.
***************************************************************************/
typedef struct
    {
    UINT8  elementId;
    UINT8  length;
    UINT16 atimWindow;
    } _WRS_PACK_ALIGN(1) DOT11_IE_IBSS;

/**************************************************************************
*  DOT11_IE_COUNTRY - 802.11d parmameters
***************************************************************************/
typedef struct
    {
    UINT8 elementId;
    UINT8 length;
    char  data[DOT11_SSID_LEN];
    } _WRS_PACK_ALIGN(1) DOT11_IE_COUNTRY;


/**************************************************************************
*  DOT11_IE_ERP - Extended Rate Phy (802.11g) parameters
***************************************************************************/
#define DOT11_ERP_NONERP_PRESENT         _BIT(0)
#define DOT11_ERP_USE_PROTECTION         _BIT(1)
#define DOT11_ERP_LONG_PREAMBLE          _BIT(2)
typedef struct
    {
    UINT8  elementId;
    UINT8  length;
    UINT8  erpInfo;
    } _WRS_PACK_ALIGN(1) DOT11_IE_ERP;



/**************************************************************************
*  DOT11_ASSOC_RESP_PACKET - An association response packet
***************************************************************************/
typedef struct
    {
    DOT11_HEADER        header;        /* 802.11 Mgmt Header */
    UINT16              capabilities;  /* 16 bit capabilities field */
    UINT16              status;        /* 16 bit Status field */
    UINT16              aid;
    DOT11_IE_SUPP_RATES rates;
    } _WRS_PACK_ALIGN(1) DOT11_ASSOC_RESP_PACKET;

/**************************************************************************
*  DOT11_PS_POLL_PACKET - A powersave-poll packet
***************************************************************************/
typedef struct
    {
    UINT16              frameCtrl;
    UINT16              aid;           /* Assoc AI with bit 14,15 set */
    UINT8               bssid[DOT11_ADDR_LEN];
    UINT8               ta[DOT11_ADDR_LEN];
    } _WRS_PACK_ALIGN(1) DOT11_PS_POLL_PACKET;

/**************************************************************************
*  DOT11_AUTH_PACKET - An authentication packet
***************************************************************************/
typedef struct
    {
    DOT11_HEADER header;
    UINT16       authAlg;
    UINT16       authSeq;
    UINT16       status;
    DOT11_IE_CHAL_TEXT challenge;
    } _WRS_PACK_ALIGN(1) DOT11_AUTH_PACKET;



#define DOT11_PTK_LEN                64
#define DOT11_GMK_LEN                32
#define DOT11_GTK_LEN                32 /* MAX - only 128 bits for AES */
#define DOT11_KEK_LEN                16
#define DOT11_KCK_LEN                16
#define DOT11_TK_LEN                 32 /* MAX - only 128 bits for AES */
#define DOT11_TK_AES_LEN             16
#define DOT11_TK_TKIP_LEN            32
#define DOT11_RSN_PASSPHRASE_MAX     63
/* The length of the global key counter, in bytes.  It should be 256 bits */
#define DOT11_GKC_LEN                32
#define DOT11_PMK_LEN                32
typedef UINT8 DOT11_PMK[DOT11_PMK_LEN];

#define DOT11_PRF_KEY_MAX           128
#define DOT11_PRF_PREFIX_MAX         64
#define DOT11_PRF_DATA_MAX          256

/**************************************************************************
* DOT11_EAPOL_KEY_PKT - This structure contains the format of an EAPOL-Key
*                  Packet.  Most EAPOL packets are parsed in the 802.1X
*                  code, with the exception of this frame.  
**************************************************************************/
#define DOT11_EAPOL_REPLAY_LEN       8
#define DOT11_EAPOL_KEYRSC_LEN       8
#define DOT11_EAPOL_KEYID_LEN        8
#define DOT11_EAPOL_IV_LEN           16
#define DOT11_EAPOL_MIC_LEN          16
#define DOT11_NONCE_LEN              32

/* This structure includes the EAPOL Header.  Note that the EAPOL-Key packet is
misaligned due to the <type> field - data should be accessed using byte 
operations only. */
typedef struct
    {
    /* EAPOL Packet Header */
    UINT8    version;
    UINT8    eapolType;
    UINT16   length;
    
    /* EAPOL-Key Packet */
    UINT8    type;
    UINT8    keyInfo[sizeof(UINT16)];
    UINT8    keyLen[sizeof(UINT16)];
    UINT8    replayCtr[DOT11_EAPOL_REPLAY_LEN];
    UINT8    nonce[DOT11_NONCE_LEN];
    UINT8    iv[DOT11_EAPOL_IV_LEN];
    UINT8    rcvSeqCtr[8];
    UINT8    keyId[DOT11_EAPOL_KEYID_LEN];     /* Reserved in 802.11 */
    UINT8    mic[DOT11_EAPOL_MIC_LEN];
    UINT8    keyDataLen[2];

    /* The key data would follow here, if any */
    } _WRS_PACK_ALIGN(1) DOT11_EAPOL_KEY_PKT;


/* The size of the EAPOL packet header */
#define DOT11_EAPOL_HEADER_SIZE      4

/* The defined EAPOL type for an EAPOL-key packet */
#define DOT11_EAPOL_TYPE_KEY         3

#define DOT11_EAPOL_VERSION          1

/* The defined keytype for IEEE 802.11 */
#define DOT11_EAPOL_KEYTYPE_WPA      254
#define DOT11_EAPOL_KEYTYPE_11i      2

#define DOT11_RSN_MAX_KDE            1024

/* The length of the KDE header is calculated as follows: 
*
*  type        1 
*  length      1  does not include type or length fields
*  OUI         3
*  dataType    1
*/
#define DOT11_EAPOL_KDE_HEADER_LEN   6

/* A GTK KDE element has additional overhead - 2 bytes for the keyId */
#define DOT11_EAPOL_KDE_GTK_HEADER_LEN   8

#define DOT11_EAPOL_KDE_TYPE_GTK     1
#define DOT11_EAPOL_KDE_TYPE_STAKEY  2
#define DOT11_EAPOL_KDE_TYPE_MACADDR 3
#define DOT11_EAPOL_KDE_TYPE_PMKID   4

#define DOT11_EAPOL_KDE_KEYINDEX     3

#define DOT11_EAPOL_KDE_TXENABLE     _BIT(2)

/* This structure represents a GTK KDE in 802.11i */
typedef struct
    {
    UINT8    type;
    UINT8    length;
    UINT8    oui[3];
    UINT8    dataType;
    UINT8    keyId;
    UINT8    reserved;
    UINT8    gtk[DOT11_GTK_LEN];
    } DOT11_KDE;

#define DOT11_KEYTYPE_PAIRWISE       _BIT(3)
#define DOT11_KEYTYPE_GROUP          0
/* Bit set in the key information field.  
Note, these use bytes accesses.  The below is in the first byte [0] */
#define DOT11_EAPOL_INFO_DESC_AES    2
#define DOT11_EAPOL_INFO_DESC_RC4    1
#define DOT11_EAPOL_INFO_DESC_MASK   0x3

#define DOT11_EAPOL_INFO_KEY_MASK    0x30


#define DOT11_EAPOL_INFO_KEYTYPE     _BIT(3)

#define DOT11_EAPOL_INFO_INSTALL     _BIT(6)
#define DOT11_EAPOL_INFO_NO_INSTALL  0

#define DOT11_EAPOL_INFO_ACK         _BIT(7)
#define DOT11_EAPOL_INFO_NO_ACK      0

/* This info is in the second byte [1] */

#define DOT11_EAPOL_INFO_MIC         _BIT(8)
#define DOT11_EAPOL_INFO_NO_MIC      0

#define DOT11_EAPOL_INFO_SECURE      _BIT(9)
#define DOT11_EAPOL_INFO_NO_SECURE   0

#define DOT11_EAPOL_INFO_ERROR       _BIT(10)
#define DOT11_EAPOL_INFO_NO_ERROR    0

#define DOT11_EAPOL_INFO_REQUEST     _BIT(11)
#define DOT11_EAPOL_INFO_NO_REQUEST  0

#define DOT11_EAPOL_INFO_ENCRYPT     _BIT(12)
#define DOT11_EAPOL_INFO_NO_ENCRYPT  0

#define DOT11_EAPOL_NO_KEY_RSC      NULL
#define DOT11_EAPOL_NO_NONCE        NULL
#define DOT11_EAPOL_NO_RSN_IE       NULL
#define DOT11_EAPOL_NO_GTK          NULL
#define DOT11_EAPOL_NO_KEY_DATA     NULL

/* These are the keyInfo combinations that are tested on in 
dot11RsnEapolReceive() */
#define DOT11_EAPOL_4WAY_MASK DOT11_EAPOL_INFO_KEYTYPE | \
    DOT11_EAPOL_INFO_INSTALL | DOT11_EAPOL_INFO_ACK | DOT11_EAPOL_INFO_MIC | \
    DOT11_EAPOL_INFO_SECURE | DOT11_EAPOL_INFO_ERROR | \
    DOT11_EAPOL_INFO_REQUEST 

#define DOT11_EAPOL_4WAY_A (DOT11_KEYTYPE_PAIRWISE | DOT11_EAPOL_INFO_ACK)
#define DOT11_EAPOL_4WAY_B (DOT11_KEYTYPE_PAIRWISE | DOT11_EAPOL_INFO_MIC)
#define DOT11_EAPOL_4WAY_C (DOT11_KEYTYPE_PAIRWISE | DOT11_EAPOL_INFO_ACK | \
                           DOT11_EAPOL_INFO_MIC)
#define DOT11_EAPOL_4WAY_D (DOT11_KEYTYPE_PAIRWISE | DOT11_EAPOL_INFO_MIC)
#define DOT11_EAPOL_GROUP_1 (DOT11_KEYTYPE_GROUP | DOT11_EAPOL_INFO_ACK | \
                           DOT11_EAPOL_INFO_MIC)
#define DOT11_EAPOL_GROUP_2 (DOT11_KEYTYPE_GROUP | DOT11_EAPOL_INFO_MIC)


#define DOT11_GROUP_REKEY_TIME (sysClkRateGet() * 60 * 2)

/* This defines the number of bytes to remove from the front of the RC4 
keystream in order to discard bytes that may reveal key bits */
#define DOT11_EAPOL_RC4_OFFSET       256


/* This is the size of a TSC (for TKIP) or a PN (for AES).  They both serve 
the same function, they just depend on the chosen algorithm */
#define DOT11_TSC_LEN                6

#define DOT11_BYTEARRAY_INC(ba, numBytes) {\
    int i=-1;\
    do {\
        ba[++i]++;\
    } while ((ba[i] == 0) && (i<(numBytes-1)));}

#define DOT11_BYTEARRAY_INC_BE(ba, numBytes) {\
    int i = numBytes;\
    do {\
        ba[--i]++;\
    } while ((ba[i] == 0) && (i >= 0));}


/* This copies the given byte array, reversing the order of the bytes */
#define DOT11_BE_COPY(src,dst,len) {\
   int i;\
   for (i = 0; i < len; i++) {\
      (dst)[(len-1)-i] = (src)[i];\
   }}


#define DOT11_KSL_HASH(macAddr)    ((macAddr[3]) ^ (macAddr[4]) ^ (macAddr[5]))
#define DOT11_KSL_MAX_HASH               256


/* The amount of time te KSL entry allocation routines will wait for the 
semaphore before giving up */
#define DOT11_KSL_ALLOC_TIME       (sysClkRateGet() / 8)

/* The value of staticCount for a dynamic KSL entry */
#define DOT11_KSL_DYNAMIC          0


/**************************************************************************
*  DOT11_FOURWAY_STATE - definitions used in pKsl->fourWayState
***************************************************************************/
/* States that apply to both the AP and the STA */
#define DOT11_FOURWAY_INIT            0
#define DOT11_FOURWAY_ESTABLISHED     10

/* States that apply to the AP */
#define DOT11_FOURWAY_SENT_1          1
#define DOT11_FOURWAY_GOT_2           2
#define DOT11_FOURWAY_SENT_3          3
#define DOT11_FOURWAY_GOT_4           4

/* States that apply to the STA */
#define DOT11_FOURWAY_GOT_1           6
#define DOT11_FOURWAY_SENT_2          7
#define DOT11_FOURWAY_GOT_3           8
#define DOT11_FOURWAY_SENT_4          9


/**************************************************************************
*  DOT11_AUTH_ALGS - Supported MAC layer authentication algorithms
***************************************************************************/
#define DOT11_AUTH_OPEN            0
#define DOT11_AUTH_SHARED_KEY      1
#define DOT11_AUTH_NETWORK_EAP     128

/* This isn't an official 802.11 authtype, but it is used by the driver to 
mean "any" authtype */
#define DOT11_AUTH_ALL             3

/*****************************************************************************
* DOT11_AUTH_SEQ - macros for ease of reading
***************************************************************************/

#define DOT11_AUTH_SEQ_1           1
#define DOT11_AUTH_SEQ_2           2
#define DOT11_AUTH_SEQ_3           3
#define DOT11_AUTH_SEQ_4           4


/**************************************************************************
*  RATE CONTROL TASK 
***************************************************************************/
#define DOT11_RC_DEPTH             256  /* Must be power of two */

/* Reevaluate the link this many packets. */
#define DOT11_RC_EVAL              (DOT11_RC_DEPTH / 2)  

#define DOT11_RC_STATUS_SUCCESS    1
#define DOT11_RC_STATUS_RETRY_OK   2
#define DOT11_RC_STATUS_RETRY_FAIL 3
#define DOT11_RC_STATUS_FAIL       4


/* This determines how often the rate control task runs, in seconds. */
#define DOT11_RC_EVAL_TIME         2 /* Seconds */

#define DOT11_RC_TASK_NAME "tDot11RC%d"
#define DOT11_RC_TASK_PRI          70
#define DOT11_RC_STACK_SIZE        (10 * 1024)

/* These values specify the threshold for a rate change.  They are expressed in
the ratio of total packets to failed packets or retries (note: more than one 
retry per packet is possible) to avoid floating point math.  A higher value 
represents a more stable link*/

#define DOT11_RC_DOWN_T_TO_R       6 /* 5 == 20 % retries */
#define DOT11_RC_DOWN_T_TO_F     500 /* 1000 == 0.01 % failure */

#define DOT11_RC_UP_T_TO_R         50 /* 33 ~= 3% retries */ 
#define DOT11_RC_UP_T_TO_F       8000 /* 6250 == 0.016 % retries */

/* How many retries a failed packet counts as.  Adjusting this affects how much
a missed packet affects the rate */
#define DOT11_RC_RETRY_FAIL_WEIGHT 16

/* The minimum number of packets that need to be received in order for the 
rate control algorithm to run. */
#define DOT11_RC_MIN_PACKET         4

/*************************************************************************
* DOT11_COUNTRY_DISC - Country discovery structure, used by
*                      dot11SmeEssCcChoose()
**************************************************************************/

#define DOT11_SCAN_COUNTRY_MAX              8

typedef struct 
    {
    int countryCode;
    int num;
    } DOT11_COUNTRY_DISC;


/* Different power-save modes */
#define DOT11_POWER_ACTIVE          0
#define DOT11_POWER_SLEEP           1
#define DOT11_POWER_PROB            2

/*************************************************************************
* DOT11_RC_INFO - Info for the rate control task.  Part of SME.
**************************************************************************/
typedef struct dot11_rc_info
    {
    /* The number of packets since the last time the RC task was run on this 
    KSL entry. */
    UINT32            packetTotal;

    /* Running sum of the number of retries since the last time the RC task
    was run on this KSL entry. */
    UINT32            retryTotal;  

    /* Running sum of the number of transmit failures (usually due to excessive
    retries) since the last time the RC task was run */
    UINT32            failureTotal;

    /* Running sum of the SSI since the last time the RC task was run.  Div by
    "packetTotal" to get the average SSI */
    UINT32            ackTotal;    
        
    } DOT11_RC_INFO;




/**************************************************************************
*  DOT11_KSL_ENTRY - An entry in the Known Station List
***************************************************************************/
typedef struct kslEntry
    {
    struct kslEntry *    pNext;
    
    /* The static count is the count of the number of reasons why this entry
    is static (reasons include valid ACL entry or key mapping entry).  As one
    entry is cleared, the count is decremented, until the entry becomes
    dynamic again (count <= 0) */
    int                  staticCount;

    UINT8                macAddr[DOT11_ADDR_LEN];
    int                  dot11Mode;  /* Is it an AP, STA or IBSS */ 
    UINT32               timestamp;  /* When did we last hear from it */
    DOT11_RC_INFO        rcInfo   ;  /* Rate control info, stats */
    DOT11_RATES          suppRates;      /* Supported rates for entry */
    UINT16   capabilities; /* 802.11 capabilities field */

    /* Rates used to communicate with this station.  It is the intersection
    of the supported rates for this station, the supported rates for the
    remote station and the allowed rates as set by the user.  Note that
    these rates are expected to be in order from slowest to fastest.  */
    DOT11_RATES          actualRates;

    UINT32               currentTxRate;
    UINT32               currentTxRateIndex;
    UINT32               lastRxRate;

    /* This values is used to inform the HDD which key mapping entry is to be
    used for this destination.  This is the unicast key for this station.  If 
    not set, then the multicast key from the DPE will be used if present. The
    decryptIndex is used only with TKIP to allow for separate TX and RX 
    entries (different MICs). */
    INT32                uniDecryptIndex;
    INT32                uniEncryptIndex;
    UINT32               uniEncryptType;

    /* The SSID that this entry is connected to. */
    char                 ssid[DOT11_SSID_LEN + 1];
    
    /* This KSL_Entry is access controlled.  The type of control is left
    up to the controlling SME module */
    BOOL                 accessControlled;
 
    /* These entries are used by WIOCSDOT1XPORTSTATUS to determine if packets
    are allowed to be transmitted through the port */
    BOOL                 dot1xControlled;
    BOOL                 dot1xAllowed;
    
    /* These records are used to keep track of the advertised security 
    policies */
    UINT32               secPol;
    UINT32               authPol;
    UINT32               ciphPol;
    UINT32               groupPol;
    UINT32               rsnCap;

    /* These records keep track of the chosen security policies */
    UINT32               negSecPol;
    UINT32               negAuthPol;

    /* This contains the Pairwise Master key, and a flag determining whether
    this is a valid PMK */
    UINT8                pmk[DOT11_PMK_LEN];
    BOOL                 pmkValid;
    
    /* The variables control the state of the four-way state machine.  The
    timer is used to wait a limited time for a reply before retransmitting */
    UINT32               fourWayState;

    INT32                fourWayGlobalTimer;
    INT32                eapolMsgTimer;
    
    /* The dervied keys are generated from the combination of the PMK, the 
    local nonce and the remote nonce */
    BOOL                 derivedKeysValid;
    UINT8                kck[DOT11_KCK_LEN];
    UINT8                kek[DOT11_KCK_LEN];
    UINT8                tk[DOT11_TK_LEN];
    
    /* The EAPOL replay counter is used for the fourway key exchange, and keeps
    track of the last key number observed or used */
    UINT8                eapolReplay[DOT11_EAPOL_REPLAY_LEN];

    /* The nonce information governs whether we have a valid nonce, and
    whether our information about the remote nonce is valid */
    UINT8                localNonce[DOT11_NONCE_LEN];
    BOOL                 localNonceValid;
    UINT8                remoteNonce[DOT11_NONCE_LEN];
    BOOL                 remoteNonceValid;

    /* These elements store the last WPA oe RSN IE used by the enitity to which
    the KSL record points.  This is used in the fourway handshake to compare 
    against to ensure the IE has not been tampered with */
    UINT8                lastRsnIe[DOT11_IE_MAX_SIZE];
    UINT8                lastWpaIe[DOT11_IE_MAX_SIZE];

    /* The transmit sequence counters store the packet number of the last 
    packet transmitted to this station, as well as the last packet received 
    from this station */
    UINT8                tscUniTx[DOT11_TSC_LEN];
    UINT8                tscUniRx[DOT11_TSC_LEN];
    
    /* Reflects the number of times that this entity has failed the fourway 
    handshake */
    UINT32               fourWayTimeouts;

    /* The tickGet() of the last connection attempt.  This is used by 
    dot11KslSSIDLookup() so that the same AP will not always be chosen if it 
    is rejecting connection attempts */
    UINT32               lastAttempt;

    /* The "type" union reflects the type of the KSL entry, NOT the SME */
    union                            
        {
        struct /* KSL_ENTRY is an AP */
            {
            int   channel;         /* Last channel we heard from entry on*/
            int      mode;            /* PHY mode last heard in */
            int      ssi;             /* Last SSI we heard from entry on */
            
            int      aid;             /* Association ID, if associated */

            /* The shared key buffer stores the last challenge text that was 
            sent to the STA */
            UINT8    skaBuffer[DOT11_AUTH_CHAL_MAX];
            int      skaLength;

            /* Offset of TIM IE in beacon packets in bytes from start of pkt*/
            UINT32   timIeOffset;        

            /* Offset of byte in complete virtual bitmap */
            UINT32   timByteOffset; 
            
            /* Mask of byte pointed to by timByteOffset for this STA */
            UINT32   timMask; 
            
            /* Information stripped from last received beacon */
            BOOL     beaconSync;
            DOT11_TIMESTAMP lastBeaconTsf;
            UINT32   beaconPeriod;
            UINT32   dtimPeriod;
            UINT32   dtimCount;
            UINT32   cfpPeriod;
            UINT32   cfpCount;
            UINT32   cfpDuration;

            UINT32   lastProbation;

            /* 802.11g compatibility information */
            BOOL     useProtection;
            BOOL     useShortTimeslot;
            BOOL     useLongPreamble;
            
            /* 802.11d information */
            UINT32   countryCode;
            
            } ap;
        struct /* KSL_ENTRY is a station in ESS mode  */
            {
            int   rate;                  /* Last rate we heard from entry on */
            int   aid;                   /* Association ID */
            BOOL  authenticatedSka;      /* Has passed stage 1 of SKA */
            BOOL  authenticated;         /* Has passed final stage of auth */
            BOOL  associated;            /* Assoc success sent */

            /* The shared key buffer stores the last challenge text that was 
            sent to the STA */
            UINT8 skaBuffer[DOT11_AUTH_CHAL_MAX];
            int   skaLength;   

            BOOL ratesUpdated;          /* Do we have rates for this device */

            BOOL powerManaged;          /* Whether this station is in PM */

            M_BLK_ID pmQueueHead;       /* Removal point */
            M_BLK_ID pmQueueTail;       /* Insertion point */

            } sta;
        struct /* KSL_ENTRY is a STA in IBSS mode */
            {
            int channel;                 /* Last channel it was heard on */
            int mode;                    /* PHY mode last heard in */
            int ssi;              
            
            UINT16 atimWindow;
            UINT16 beaconInterval;       /* BI used by this sta */

            UINT8 bssid[DOT11_ADDR_LEN]; /* BSSID it's connected to */
            
            DOT11_TIMESTAMP  lastBeaconTsf;  /* Their TSF */
            DOT11_TIMESTAMP  ourTsf;    /* When we received it */
            
            BOOL ratesUpdated;          /* Do we have rates for this device */
            
            /* 802.11d information */
            UINT32   countryCode;
            } ibss;
        } type;   
    } DOT11_KSL_ENTRY;


/**************************************************************************
*  DOT11_FRAGMENT - Reassembly space for ingress fragment
***************************************************************************/
typedef struct
    {
    BOOL          used;         /* Determines if this slot is used */
    UINT8         addr2[DOT11_ADDR_LEN];
    UINT8         addr1[DOT11_ADDR_LEN];
    UINT16        sequence;     /* seq out of seqCtl field */
    INT32         lastFrag;     /* The last fragment that was received */
    
    int           timerId;      /* Identifies timer */

    M_BLK_ID      pHead;        /* The head of the reassembled packet*/
    M_BLK_ID      pLast;        /* Pointer to last MBlk for convenience */
    } DOT11_FRAGMENT;
#define DOT11_MAX_REASSEMBLY    16

/**************************************************************************
*  DOT11_REASSEMBLY - Structure used to store packet statistics 
***************************************************************************/
typedef struct
    {
    DOT11_FRAGMENT packet[DOT11_MAX_REASSEMBLY];
    } DOT11_REASSEMBLY;

#define DOT11_FRAGMENT_LAST     _BIT(15)
#define DOT11_FRAGMENT_MASK     0x000f

#define DOT11_FRAGMENT_MIN_SIZE 256

#define DOT11_FRAGMENT_MAX_NUM  16


typedef struct
    {
    int a;
    } DOT11_SW_KEY_TABLE;

typedef struct
    {
    int a;
    } DOT11_TX_POWER_RANGE;





#define DOT11_MAX_DEFAULT_KEY        4
#define DOT11_MAX_KEYS              64

/* This is a magic number passed to pDot11->hdd->hwEncryptionKeySet() to 
signal it to look for the first available unicast key slot */
#define DOT11_KEYINDEX_SEARCH      65536

/* This is a parameter passed to hdd->rawSend() that specifies no encryption*/
#define DOT11_KEYINDEX_NONE          -1




/**************************************************************************
*  DOT11_KEYTAB_ENTRY - An entry in the soft key table 
***************************************************************************/
typedef struct
    {
    BOOL used;
    DOT11_KSL_ENTRY * pKsl;
    } DOT11_KEYTAB_ENTRY;




/*****************************************************************************
* DOT11_RX_FUNC - A type representing a function pointer to a receive function
*                 as used by the rxMap in the Hdd.
*****************************************************************************/
typedef STATUS (* DOT11_RX_FUNC)(DOT11_FW * pDot11, M_BLK_ID pMblk, 
                                UINT32 rate, UINT8 ssi);

/*****************************************************************************
* DOT11_RX_FILTER - Filter describing which packets will be received by the
*                   hardware
*****************************************************************************/

#define DOT11_RX_FILTER_NONE         0

/* DOT11_RX_FILTER_UNI - Unicast packets, with the stations addr in addr1 */
#define DOT11_RX_FILTER_UNI          _BIT(0)

/* DOT11_RX_FILTER_MULTI - Multicast packets matching filter */
#define DOT11_RX_FILTER_MULTI        _BIT(1)

/* DOT11_RX_FILTER_BROAD - Broadcast (non-matching BSSID)packets */
#define DOT11_RX_FILTER_BROAD        _BIT(1)

/* DOT11_RX_FILTER_BEACON - Beacons */
#define DOT11_RX_FILTER_BEACON       _BIT(2)

/* DOT11_RX_FILTER_PROBE_REQ - Broadcast management packets */
#define DOT11_RX_FILTER_PROBE_REQ    _BIT(3)

/* DOT11_RX_FILTER_CONTROL - All 802.11 Control frames */
#define DOT11_RX_FILTER_CONTROL      _BIT(4)

/* DOT11_RX_FILTER_PROMISC - All frames */
#define DOT11_RX_FILTER_PROMISC      _BIT(5)


IMPORT const char * dot11StateNames[];

#define DOT11_DEFAULT_AUTH_TIMEOUT  (sysClkRateGet() / 20)
#define DOT11_DEFAULT_ASSOC_TIMEOUT (sysClkRateGet() / 20)


/*****************************************************************************
* DPE_OBJ - Object representing the Data Path Entity          
*****************************************************************************/
typedef struct /* DPE_OBJ */
    {
    STATUS (*free)(DOT11_FW * pDot11);
    STATUS (*endSend)(END_OBJ * pEnd, M_BLK_ID pMblk);
    STATUS (*endReceive)(DOT11_FW * pDot11, M_BLK_ID pMblk, 
                         UINT32 rate, UINT8 SSI);
    STATUS (*fragThresholdSet)(DOT11_FW * pDot11, UINT32 fragThresh);
    STATUS (*fragThresholdGet)(DOT11_FW *  pDot11,
                               UINT32 * fragThresh);
    STATUS (*endPollSend)(END_OBJ* pEnd, M_BLK_ID pMblk);
    STATUS (*endPollRcv)(END_OBJ* pEnd, M_BLK_ID pMblk);
    STATUS (*transmitQueueFlush)(DOT11_FW * pDot11);    

    /* The reassembly buffer stores packet fragments awaiting reassembly */
    DOT11_REASSEMBLY     reassemblyBuff;

    /* Packets above this size will be fragmented */
    UINT32               fragThreshold;


    DOT11_EX_POLICY      exclusionPolicy;

    /* These are the multicast keys for the device (multicast as in "all 
    devices, not as in unicast and multicast packets) */
    DOT11_ENCRYPT_TYPE   multiEncryptType;
    UINT32               multiEncryptIndex;

    /* Counters for TKIP/AES multicast packets */
    UINT8                tscMultiTx[DOT11_TSC_LEN];
    UINT8                tscMultiRx[DOT11_TSC_LEN];

    UINT8                gmk[DOT11_GMK_LEN];
    UINT8                gtk[DOT11_GTK_LEN];
    BOOL                 gtkValid;
    UINT8                gNonce[DOT11_NONCE_LEN];
    
    /* Timer for group re-keying */
    INT32                groupRekeyTimer;
    UINT32               groupRekeyTime;

    /* This array keeps track of the mappings between encrypt and decrypt keys
    for the shared keys.  It will be set to {0,1,2,3} unless a TKIP key 
    (requiring a separate encrypt key) is present in the shared keys, in 
    which case, the appropriate entry in the array will reflect the encrypt
    key to be used.  */
    UINT8                decryptToEncrypt[DOT11_MAX_DEFAULT_KEY];

    /* This specifies the last initialization vector used on an egress packet*/
    UINT32               currentIV;
    
    /* Protects the order of the transmission path */
    SEM_ID               transmitSem;

    /* This queues up packets that attempted transmission while the link was
    not up. Upon resumption of the link, these packets will be sent before any 
    fresh packets. Use a head and tail for quick insertion and removal.*/
    M_BLK_ID             transmitQueueHead;    
    M_BLK_ID             transmitQueueTail;

    } DPE_OBJ;

/*****************************************************************************
* DOT11_KSL_OBJ - the Known Station List object
*****************************************************************************/
typedef struct /* DOT11_KSL_OBJ */
    {
    /* The init routine, dot11KslInit() is called directly from the SME to 
    create this structure */
    STATUS (*free)(DOT11_FW * pDot11);
    STATUS (*show)(int unitNum);
    STATUS (*lock)(DOT11_FW * pDot11);
    STATUS (*unlock)(DOT11_FW * pDot11);

    STATUS (*flush)(DOT11_FW * pDot11);

    DOT11_KSL_ENTRY * (*lookup)(DOT11_FW * pDot11, UINT8 * macAddr);
    DOT11_KSL_ENTRY * (*ssidLookup)(DOT11_FW * pDot11, char * ssid, 
                                   int dot11Mode);

    DOT11_KSL_ENTRY * (*rxUpdate)(DOT11_FW * pDot11, UINT8 * macAddr, 
                                  int rate, int ssi);
    DOT11_KSL_ENTRY * (*txUpdate)(DOT11_FW * pDot11, UINT8 * macAddr, 
                                  BOOL success, UINT32 nRetries, 
                                  UINT32 ackSSI);
    DOT11_KSL_ENTRY * (*add)(DOT11_FW * pDot11, UINT8 * macAddr);
    STATUS (*delete)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);
    STATUS (*lastAttemptReset)(DOT11_FW * pDot11);

    
    /* Private data members */

    /* This is the pointer to the head of the free pool of KSL entries and the
    semaphore to guard the LL */
    DOT11_KSL_ENTRY * pPool;
    DOT11_KSL_ENTRY * pFreeEntry;
    int poolUsed;
    int poolMaxUsed;
    SEM_ID poolSem;

    DOT11_KSL_ENTRY * list[DOT11_KSL_MAX_HASH];
    SEM_ID            lockSem;          /* Table protection */

    int               cleanupTimer;
    

    } DOT11_KSL_OBJ;

/*****************************************************************************
* DOT11_RSN_OBJ - Specialized SME OBJ for RSN use.  Only used in SME_OBJ
*****************************************************************************/
typedef struct /* DOT11_RSN_OBJ */
    {

    STATUS      (*free)(DOT11_FW * pDot11);
    INT32       (*rsnIeCreate)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl, 
                         UINT8 * buffer);
    INT32       (*wpaIeCreate)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl, 
                         UINT8 * buffer);
    STATUS      (*ieProcess)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl,
                             UINT8 * buffer);
    UINT32      (*groupPolicyRecalc)(DOT11_FW * pDot11, 
                                     DOT11_KSL_ENTRY * pKsl);
    STATUS      (*eapolPktReceive)(DOT11_FW * pDot11, M_BLK_ID pMblk);

    STATUS      (*pskSet)(DOT11_FW * pDot11, const UINT8 * pKey);
    STATUS      (*pmkSet)(DOT11_FW * pDot11, const UINT8 * pKey);
    STATUS      (*passphraseSet)(DOT11_FW * pDot11, const char * passphrase);

    STATUS      (*fourwayStart)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);
    STATUS      (*fourwayTimeout)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl);
    STATUS      (*gtkRecalc)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl, 
                             BOOL force);
    STATUS      (*micFailureProcess)(DOT11_FW * pDot11, UINT8 * srcAddr);

    UINT8       globalKeyCounter[DOT11_GKC_LEN];
    
    /* Keeps track of the tickGet() of the last MIC failure.  Used by 
    dot11RsnMicFailureProcess() to enforce TKIP countermeasures.  */
    INT32       lastMicFailure;

    /* TRUE if TKIP countermeasures are active.  Prevents association to and
    from stations with TKIP cipher */
    BOOL        micLockout;
    
    /* timerId for the dot11RsnMicReenable() */
    UINT32      micLockoutTimer;

    /* The source address of the packet that had the MIC error */
    UINT8       micLockoutAddr[DOT11_ADDR_LEN];

    } DOT11_RSN_OBJ;

/*****************************************************************************
* DOT11_ESS_OBJ - Specialized SME OBJ for ESS use.  Only used in SME_OBJ
*****************************************************************************/
typedef struct /* DOT11_ESS_OBJ */
    {
    /* PRIVATE */    
    DOT11_ESS_SM       sm;                  /* State machine object */

    MSG_Q_ID           scanMsgQ;            /* Message queue for scan task */
    int                scanTaskId;          /* TID for deleting scan task */

    int                probationTimer;      /* Timer to recove from link p */

    int                authTimer;           /* Timer for auth and assoc */

    /* This is a pointer to the KSL_ENTRY of the currently connected BSS */
    DOT11_KSL_ENTRY *  pKslAp;

    } DOT11_ESS_OBJ;

/*****************************************************************************
* DOT11_IBSS_OBJ - Specialized SME OBJ for IBSS use.  Only used in SME_OBJ
*****************************************************************************/
typedef struct /* DOT11_IBSS_OBJ */
    {
    M_BLK_ID           pMblkBeacon;     /* Cluster allocated for beacons */
    BOOL               beaconing;       /* Tue if beacons are being sent */
    BOOL               syncBeacon;      /* Are we sync'd to the IBSS's bcns */

    int                stateTid;        /* Task ID of state task; for del */
    MSG_Q_ID           stateMsgQ;       /* Message queue for state task */

    int                state;           /* Current state of SM */

    int                beaconInterval;  /* Time (in tu) between beacons */
    int                atimWindow;      /* Window after beacon for ATIM */

    /* This is the pointer to the KSL_ENTRY that we used to create the 
    IBSS.  This is just one station in the IBSS, but it should be sufficient
    to get the IBSS parameters from.  If we get a beacon with a later timestamp
    than this one, then we can shift to using that one */
    DOT11_KSL_ENTRY *       pKslIbss;
    } DOT11_IBSS_OBJ;

/*****************************************************************************
* DOT11_AP_OBJ - Specialized SME OBJ for AP use.  Only used in SME_OBJ
*****************************************************************************/
/* The timeout for the TIVB is small so that we don't break beacons waiting
for it */
#define DOT11_TIVB_SEM_TIMEOUT          (2)

typedef struct /* DOT11_AP_OBJ */
    {
    int channel;
    M_BLK_ID           pMblkBeacon;     /* Cluster allocated for beacons */
    int                beaconInterval;  /* Time (in tu) between beacons */
    DOT11_IE_TIM *     pTim;            /* Pointer to the TIM IE */
    UINT8              tivb[DOT11_MAX_PVB]; /* Complete TIVB */
    INT32              tivbStart;       /* Start of real data in the tivb*/
    INT32              tivbStop;        /* End of data in the tivb */
    SEM_ID             tivbSem;         /* Sem protecting TIVB */

    UINT32             dtimPeriod;      /* number of bcns per DTIM */
    UINT32             dtimCount;       /* number of bcns until DTIM */
    UINT32             cfpPeriod;       /* number of bcns per CFP */
    UINT32             cfpCount;        /* number of bcns until CFP */
    UINT32             cfpDuration;     /* Length of CFP, in tu */
    
    BOOL               respondBcastSsid; /* Respond to requests for ANY ssid */
    BOOL               showSsidInBeacon; /* Respond to requests for ANY ssid */

    int                beaconTid;       /* Beacon task-ID */
    SEM_ID             beaconSem;       /* Semaphore to wake beacontask */

    UINT32             aclMode;         /* Access Control List mode */

    UINT16             lastAid;         /* Last AID allocated */

    /* A pointer to the real raw packet send */
    STATUS (*origRawPacketSend)(DOT11_FW * pDot11, M_BLK_ID pMBlk, int rate,
                            int keyIndex);

    /* 802.11g compatibility info */
    
    /* Set to TRUE if a non-ERP station is present in 11g network */
    BOOL               nonErpPresent;
    
    /* Set to TRUE if all ERP stations are required to use protection */
    BOOL               useProtection;

    /* Set to TRUE if use of short time slot is allowed in this BSS */
    BOOL               useShortTimeslot;

    /* Set to TRUE if use of short preamble is not allowed in this BSS */
    BOOL               useLongPreamble;

    /* Pointer to the ERP IE in the beacon, for easy updating of 802.11g info
    as stations join.  Can be NULL is not in 11g mode */
    DOT11_IE_ERP *     pErpIe;

    /* Pointer to the capabilities field in the beacon */
    UINT16 *           pCaps;

    } DOT11_AP_OBJ;

/*****************************************************************************
* SME_OBJ - Object representing the Station Management Entity. 
*****************************************************************************/
typedef struct /* SME_OBJ */
    {
    /* PUBLIC members */

    
    /* Frees the entire SME, including the current SME module, if necessary */
    STATUS (*free)(DOT11_FW *  pDot11);

    /* Starts the specified mode.  Will de-init old mode if one was started */
    STATUS (*modeStart)(DOT11_FW *  pDot11, int dot11Mode);

    /* Frees just the current SME module */
    STATUS (*modeStop)(DOT11_FW *  pDot11);

    /* A helper function called by modeStop that stops the currently selected
    SME module */
    STATUS (*modeFree)(DOT11_FW *  pDot11);

    /* Show routine for the specific mode */
    STATUS (*modeShow)(DOT11_FW *);

    int (*endIoctl)(END_OBJ* pDrvCtrl, unsigned int cmd, caddr_t data);

    /* IOCTL routines specific to the SME type.  Implemented in 
    dot11SmeXXXLib.c */
    int (*smeSpecificIoctl)(DOT11_FW * pDrvCtrl, unsigned int cmd, 
                            caddr_t data);

    /* IOCTL routines common to all SME types.  Implemented in dot11SmeLib.c */
    int (*smeCommonIoctl)(DOT11_FW * pDrvCtrl, unsigned int cmd, caddr_t data);

    /* Notifies the SME about link events */
    VOID (*linkEventNotify)(DOT11_FW *  pDot11, int event);

    /* Perform a BSS scan */
    INT32 (*bssScanDo)(DOT11_FW *  pDot11, char * ssid, 
                       DOT11_SCAN_RESULTS * results, int numresults);

    int (*dot11StateGet)(DOT11_FW *  pDot11);

    STATUS (*endMCastAddrGet)(END_OBJ* pEnd,MULTI_TABLE* pTable);
    STATUS (*endMCastAddrAdd)(END_OBJ* pEnd, char * address);
    STATUS (*endMCastAddrDel)(END_OBJ* pEnd, char * address);
    STATUS (*reset)(DOT11_FW * pDot11);
    
    STATUS (*txMultiRateSet)(DOT11_FW * pDot11, UINT32 rate); 
    UINT32 (*txMultiRateGet)(DOT11_FW * pDot11); 
    STATUS (*txUniRateSet)(DOT11_FW * pDot11, DOT11_RATES * pRate); 
    STATUS (*txUniRateGet)(DOT11_FW * pDot11, DOT11_RATES * pRate); 

    /* PRIVATE */
    STATUS (*nullDataSend)(DOT11_FW * pDot11,UINT8 * pDstAddr, BOOL toDs);

    STATUS (*probeReqSend)(DOT11_FW * pDot11,DOT11_IE_SSID * pSsid,
                               DOT11_RATES * pRates);

    STATUS (*authSend)(DOT11_FW * pDot11, UINT8 * pDstMacAddr, UINT16 authAlg,
                        UINT16 authSeq, UINT16 status, int chalLen, 
                        UINT8 * pChallenge);
    STATUS (*assocReqSend)(DOT11_FW * pDot11, UINT8 * pDstMacAddr,
                            DOT11_CAPABILITIES * pCap, UINT16 listenInt,
                            DOT11_IE_SSID *pSsid, DOT11_RATES * pRates);
    STATUS (*assocRspSend)(DOT11_FW * pDot11, UINT8 * pDstMacAddr,
                            DOT11_CAPABILITIES * pCap, UINT16 status, 
                           UINT16 aid, DOT11_RATES * pRates);
    STATUS (*deauthSend)(DOT11_FW * pDot11, UINT8 * pDstAddr, UINT16 reason);
    STATUS (*disassocSend)(DOT11_FW * pDot11, UINT8 * pDstAddr, UINT16 reason);
    DOT11_RX_FUNC assocReceive;
    DOT11_RX_FUNC disassocReceive;
    DOT11_RX_FUNC authReceive;
    DOT11_RX_FUNC deauthReceive;
    DOT11_RX_FUNC beaconReceive;
    DOT11_RX_FUNC nullDataReceive;
    DOT11_RX_FUNC pollReceive;

    STATUS (*essJoin)(DOT11_FW * pDot11, char * pSsid);
    UINT32 (*linkStatusGet)(DOT11_FW * pDot11);
    UINT32 (*assocCallback)(DOT11_FW * pDot11, DOT11_KSL_ENTRY * pKsl, 
                           UINT32 event);

    /* Called by the HDD when it needs the beacon updated.  Only used for AP 
    mode */
    STATUS (*beaconUpdate)(DOT11_FW * pDot11);

    /* Regenerates the list of channels that match the current radio mode */
    STATUS (*scanListBuild)(DOT11_FW * pDot11);

    /* Determines whether a BSS scan will send Probe Requests and use info from
    Probe Responses to locate BSSes. */
    BOOL                  activeScan;

    /* Determines whether a BSS scan will use info from Beacons to locate
    BSSes. */
    BOOL                  passiveScan;
    DOT11_CHANNEL_LIST    scanList;
    
    /* The TID for the rate control task.  Used in the deinitialization of the 
    SME. */
    int                   rateControlTask;

    /* This semaphore is given to force an update of the rc task. */
    SEM_ID                rcForceUpdate;

    /* Rates that this station supports, in IEEE 802.11 format (ie. in units of
    500 kbps, with 0x80 masked over for basic (required) rates) */
    DOT11_RATES           suppRates;   
    
    /* These are the rates that the user wishes to use.  They may or may not
    be a subset of the supported rates - the intersection of the two sets will
    be used */
    DOT11_RATES           allowedRates;
    
    /* This is the rate that is used to transmit management and control frames,
    as well and multicast and broadcast frames.  It is typically one of the
    station's basic rates, but is not required to be */
    UINT32                bcastRate;
    
    /* The desired broadcast rate is that set by WIOCSBCASTRATE.  It is taken
    into consideration when choosing a new bcast rate.  If this rate is not in
    the BSS basic rate set, the next lowest basic rate will be chosen.  */
    UINT32                desiredBcastRate;

    /* This is the list of channels available and the mode they're available 
    in */
    DOT11_CHANNEL_LIST    channelList;

    /* This is the default authentication method for a station, and the allowed
    authentication method for an AP */
    UINT32                authType;

    /* This controls whether power management mode in on in ESS mode */
    BOOL                  powerManagement;

    /* This is the 802.1X authentication callback.  The ESS and AP modules will
    call this function if they associate (or associate someone) or disassociate
    */
    FUNCPTR               dot1xAuthCallback;    
    UINT32                dot1xAuthCallbackParam;

    /* The user callback is used to register a callback whereby the user is
    notified of changes to the drivers state */
    FUNCPTR               userAuthCallback;

    /* These are accumulators that are used for calculating the bytes/s stats*/
    DOT11_UINT64          accRxBytesPerSec;
    DOT11_UINT64          accRxBytesPer16Sec;
    DOT11_UINT64          accTxBytesPerSec;
    DOT11_UINT64          accTxBytesPer16Sec;

    /* These are the timout values, in ticks, for authentication and 
    association messages.  These are dynamic because the MIB wants to manage 
    them */
    UINT32                authTimeout;
    UINT32                assocTimeout;

    /* TRUE if 802.11d support is turned on.  This effects all modes of
    operation */
    BOOL                  multiDomainEnabled;

    /* This is the SME specific object.v */
    union
        {
        DOT11_ESS_OBJ     ess;
        DOT11_IBSS_OBJ    ibss;
        DOT11_AP_OBJ      ap;
        } type;
    
    /* The KSL object that implements the KSL*/
    DOT11_KSL_OBJ         ksl;

    /* The Object containing routines and data for managing the RSNA */
    DOT11_RSN_OBJ         rsn;

    } SME_OBJ;


/*****************************************************************************
* HDD_OBJ - Object representing the Hardware Device Driver abstraction
*****************************************************************************/
typedef struct /* HDD_OBJ */
    {
    STATUS (*initialize)(DOT11_FW * pDot11);
    STATUS (*free)(DOT11_FW * pDot11);
    STATUS (*bringUp)(DOT11_FW * pDot11);
    STATUS (*takeDown)(DOT11_FW * pDot11);
    STATUS (*start)(DOT11_FW * pDot11);
    STATUS (*stop)(DOT11_FW * pDot11);
    STATUS (*show)(DOT11_FW * pDot11);
    STATUS (*psPollSend)(DOT11_FW * pDot11);
    STATUS (*rawPacketSend)(DOT11_FW * pDot11, M_BLK_ID pMBlk, int rate,
                            int keyIndex);
    STATUS (*dtimPacketAdd)(DOT11_FW * pDot11, M_BLK_ID pMBlk, int rate,
                            int keyIndex);
    STATUS (*dtimPacketFlush)(DOT11_FW * pDot11);
    STATUS (*rxMapRegisterInit)(DOT11_FW * pDot11,DOT11_RX_FUNC rxMap[]); 
    STATUS (*rxMapRegisterSet)(DOT11_FW *pDot11,int entry,DOT11_RX_FUNC rxMap); 
    STATUS (*macAddrGet)(DOT11_FW * pDot11, UINT8 * pmacAddr );
    STATUS (*channelSet)(DOT11_FW * pDot11, int channel, int mode);
    STATUS (*channelGet)(DOT11_FW * pDot11, int * channel, int * mode);  
    STATUS (*channelListGet)(DOT11_FW * pDot11, 
                             DOT11_CHANNEL_INFO * pChannelInfo);  
    STATUS (*pmStateSet)(DOT11_FW * pDot11, BOOL pmState); 
    BOOL   (*pmStateGet)(DOT11_FW * pDot11);  
    STATUS (*probStateSet)(DOT11_FW * pDot11, BOOL probState); 
    STATUS (*bssidSet)(DOT11_FW * pDot11, UINT8 * bssid, INT32 AID, 
                       UINT32 timOffset);
    STATUS (*suppRatesGet)(DOT11_FW * pDot11, DOT11_RATES * pRates);
    STATUS (*hwEncryptionKeySet)(DOT11_FW * pDot11, UINT8 * macAddr, 
                                 UINT32 keyNum, DOT11_KEY * pKey); 
    STATUS (*hwEncryptionKeyDel)(DOT11_FW * pDot11, UINT32 keyNum);
    int    (*hwEncryptionKeyMaxGet)(DOT11_FW * pDot11);
    
    STATUS (*staBeaconSync)(DOT11_FW * pDot11);
    
    STATUS (*beaconStart)(DOT11_FW * pDot11, M_BLK_ID pMblk,  
                          INT32 nextBeacon, int beaconInterval, int atimWin);
    STATUS (*beaconStop)(DOT11_FW * pDot11);
 
    STATUS (*rtsThresholdSet)(DOT11_FW * pDot11, UINT32 rtsThreshold); 
    UINT32 (*rtsThresholdGet)(DOT11_FW * pDot11); 

    VOID (*rxFilterSet)(DOT11_FW * pDot11, UINT32 rxFilter);

    UINT32 (*nextDtimGet)(DOT11_FW * pDot11);

    STATUS (*multicastAddressDel)(DOT11_FW * pDot11, char * pAddress);
    STATUS (*multicastAddressAdd)(DOT11_FW * pDot11, char * pAddress);

    UINT32 (*cardTypeGet)(DOT11_FW * pDot11);

    STATUS (*tsfGet)(DOT11_FW * pDot11, DOT11_TIMESTAMP * pTsf);
    
    STATUS (*countryCodeChange)(DOT11_FW * pDot11);

    STATUS (*macAddrChange)(DOT11_FW * pDot11, UINT8 * macAddr);
    
    STATUS (*txParamsSet)(DOT11_FW * pDot11, BOOL useShortPreamble, 
                          BOOL use11gProt, BOOL use11gShortSlot);
    STATUS (*controlRateSet)(DOT11_FW * pDot11, UINT8 ctrlRate);
    
    STATUS (*hwVersGet)(DOT11_FW * pDot11, char * buffer);
    STATUS (*frameLongRetrySet)(DOT11_FW * pDot11, UINT32 longRetry);
    STATUS (*frameLongRetryGet)(DOT11_FW * pDot11, UINT32 *longRetry);
    STATUS (*frameShortRetrySet)(DOT11_FW * pDot11, UINT32 shortRetry);
    STATUS (*frameShortRetryGet)(DOT11_FW * pDot11, UINT32 *shortRetry);
    STATUS (*txPowerScaleSet)(DOT11_FW * pDot11, UINT32 scale);
    STATUS (*txPowerScaleGet)(DOT11_FW * pDot11, UINT32 * scale);

    STATUS (*countryCodeIeGet)(DOT11_FW * pDot11, UINT8 * pIe);
    int    (*countryCodeNumGet)(DOT11_FW * pDot11, char * country);

    int                   dot11Type;   /* Are we an AP, STA in ESS or IBSS */

    /* Packets larger than this threhsold get sent using CTS/RTS protection*/
    UINT32                ctsRtsThreshold;

    /* This describes the wireless mode that the card is currently in.  It
    cannot contain more than one mode (unlike pDot11->radioMode) since
    it represents a physical setting */
    int curMode;
    
    /* This is the channel that the card is currently tuned to */
    int curChannel; 

    DOT11_CHANNEL_INFO * pCurChannel;

    void * pHw;           /* A pointer to a hardware specific data structure */
    
    int          pmState;  /* Current state of power management */

    UINT32        maxSleepTime;  /* in milliseconds */
    
    DOT11_RX_FUNC rxMap[DOT11_RX_MAP_NUM];

    /* The information about the beacon task */
    int           beaconTid;
    SEM_ID        beaconSem;

    /* The watchdog that is used to defer interrupts for a bit if tNetTask 
    overflows */
    WDOG_ID       intReenableWdog;
    /* Keeps track of the current value of the exponential backoff.  */
    int           intRenableTime;

    /* Keeps track of which keys are currently in use.  Applicable only to
    unicast keys */
    DOT11_KEYTAB_ENTRY keyTab[DOT11_MAX_KEYS];

    /* Used for the periodic hardware calibration timer */
    int           calTimer;
    int           calTime;

    } HDD_OBJ;


/*****************************************************************************
* DOT11_FW - The wireless framework object; the root object of the driver
*****************************************************************************/
struct dot11Framework
    {
    /* the END_OBJ must go first so that we can use the pEnd to reference this
    struct.  Conceptually, we are extending the END_OBJ */
    END_OBJ            endObj;        

    STATUS (*endLoad)(char * initString, void * pBSP);
    STATUS (*endUnload)(END_OBJ * pEnd);
    STATUS (*endStart)(END_OBJ * pEnd);
    STATUS (*endStop)(END_OBJ * pEnd);
    STATUS (*debugLevelGet)(END_OBJ * pEnd,int area);
    STATUS (*debugLevelSet)(DOT11_FW * pDot11, int area, int level);
    
    UINT8              macAddr[6];

    /* The Station Management Entity handles management and control frames
    and performs most aspects of the 802.11 protocol. */
    SME_OBJ *          sme;
    
    /* The Hardware Device Driver implements the card-specific routines to 
    talk to the card.  */
    HDD_OBJ *          hdd;
    
    /* The Data Path Entity handles data packets, implementing the receive and
    transmit path */
    DPE_OBJ *          dpe;
    
    /* The type of device - ESS, IBSS or AP */ 
    INT32              dot11Mode;
    
    /* The unit number of the device */
    INT32              unitNum;
    
    /* Base address of the device's registers */
    UINT32             baseAddr;          

    /* Base address for the memory pool */
    UINT32             dmaBufAddr;     /* Address of the DMA buffer */
    UINT32             dmaBufSize; /* Total size of the DMA buffer */     
    UINT32             dmaBufUsed; /* How much has already been allocated */  
    
    /* Interrupt request line assigned to the card */
    INT32              intVector;
    INT32              intLevel;

    /* PCI Device ID for HDD chipset dection */
    UINT32             pciDeviceId;
    
    /* PCI Vendor ID for HDD chipset dection */
    UINT32             pciVendorId;

    /* PCI Device ID for HDD chipset dection */
    UINT32             pciSubDeviceId;
    
    /* PCI Vendor ID for HDD chipset dection */
    UINT32             pciSubVendorId;

    /* PCI Vendor ID for HDD chipset dection */
    UINT32             pciChipRevId;

    /* Size of the cache line.  Typically 8 or 32 bytes.  Always power of 2 */
    int                cacheLineSize;

    /* The SSID to which the user would like us to join.  Note that this may
    be the broadcast addr, in which case the currentSsid may be different */
    char               desiredSsid[DOT11_SSID_LEN + 1];

    /* The SSID that the SME is currently working with.  Since there may be
    more than AP with a given SSID, this does not uniquely identify the 
    network */
    char               currentSsid[DOT11_SSID_LEN + 1];

    /* Radio type - controls which channels the card is allowed to access */
    UINT32             radioMode;

    /* Default channel - if the device needs a channel to create an AP or a 
    new IBSS, this is the channel chosen.  This setting does not do anything 
    in ESS mode. */
    int                defaultChannel;

    /* Current connected BSSID.  This does uniquely identify the network, since
    each BSS has to have a unique BSSID.*/
    UINT8              bssid[DOT11_ADDR_LEN];

    /* Country code - controls which channels and transmit power levels are
    available */
    int                countryCode;

    /* Current link status */
    int                linkStatus;
    
    /* Packet statistics */
    DOT11_STATS        stats;

    CL_POOL_ID         pClPool;      /* Pointer to cluster pool for END use */
    M_CL_CONFIG        mClBlkConfig; /* mbuf config table */
    CL_DESC            clDescTbl;    /* Cluster description table */
    
    /* Contains the MUX function table */
    NET_FUNCS          dot11EndFuncTable;

    /* Timer IDs for the statistics rate timers */
    int                oneSecTimer;
    int                sixteenSecTimer;
 
    /* These are the parameters that control WPA and 802.11 mode */
    UINT32 secPol;   /* Security Policy : a bitmap of allowed sec. policies */
    UINT32 authPol;  /* Authentication Policy: specifies 802.1X or PSK */
    UINT32 ciphPol;  /* Cipher Policy: Specifies list of allowed ciphers */
    
    char  rsnPassphrase[DOT11_PASSPHRASE_LEN+1];
    char  rsnPassLastSsid[DOT11_SSID_LEN + 1];
    UINT8  preSharedKey[64]; /* If authPol == PSK, then this contains the PSK*/
    BOOL   pskValid;
    
    /* This is the sequence number of the last packet received; used for duplicate detection as a fix to SPR 110780 */
    UINT16              lastSeq;

    }; /* No typedef since it had to be forward declared.  See DOT11_FW above*/

typedef struct
    {
    void   (*sysUsDelay)       (int);            
    STATUS (*cacheInval) (void *, UINT32); 
    STATUS (*cacheFlush)      (void *, UINT32); 
    UINT32 (*physToVirt) (UINT32);
    UINT32 (*virtToPhys) (UINT32);
    void   (*sysIntConnect)    (int vector, int func,        
                                int params, STATUS *result); 
    void   (*sysIntDisconnect) (int vector, int func, 
                                int params, STATUS *result); 
    
    void   (*sysIntEnable)     (INT32, STATUS *);
    void   (*sysIntDisable)  (INT32, STATUS *);

    /* Declare the SME init functions here, so that there are no hard links
    for when we want to run them */
    STATUS (*essInit)(DOT11_FW * pDot11);
    STATUS (*ibssInit)(DOT11_FW * pDot11);
    STATUS (*apInit)(DOT11_FW * pDot11);
    STATUS (*rsnInit)(DOT11_FW * pDot11);
    void (*dmaMemFree)(UINT32);
    } DOT11_BSP_FUNCS;
IMPORT DOT11_BSP_FUNCS dot11BspFuncs;




/*################################################################*/
/* These are internal calls that are only callable from within the kernel */
/*################################################################*/

typedef struct
    {
    INT32 status; /* Port status */
    UINT8 macAddr[6]; /* mac address of the port */
    } _WRS_PACK_ALIGN(1) DOT11_DOT1X_PORTSTATUS;

typedef struct param_s
    {
    UINT32 callback; /* Callback event handler */
    UINT32 cookie; /* private data */
    } _WRS_PACK_ALIGN(1) DOT11_DOT1X_PARAMS;

/* Give dot1x port status change callback */
#define WIOCSDOT1XPORTSTATUS   _IOW('x', 0x01, DOT11_DOT1X_PORTSTATUS)

/* Register authentication callback     FUNCPTR  */
#define WIOCSAUTHCALLBACK      _IOW('x', 0x02, DOT11_DOT1X_PARAMS)            

/* <Internal> Set the PMK */
#define WIOCSPMK               _IOWU('x', 0x03, DOT11_PMK)



/*
*            LEGACY IOCTL DEFINITIONS 
*/

#ifndef EIOCSWEPTYPE
 #define EIOCSWEPTYPE         (0x21d) /* Set WEP type - 64 bit or 128 bit */
#endif
#ifndef EIOCGWEPSTATUS
 #define EIOCGWEPSTATUS       (0x20f) /* Get WEP status*/
#endif
#ifndef EIOCSWEP
 #define EIOCSWEP             (0x210) /* Enable/disable WEP*/
#endif
#ifndef EIOCSWEPKEY0
 #define EIOCSWEPKEY0         (0x211) /* Set WEP key 0*/
#endif
#ifndef EIOCSWEPKEY1
 #define EIOCSWEPKEY1         (0x212) /* Set WEP key 1*/
#endif
#ifndef EIOCSWEPKEY2
 #define EIOCSWEPKEY2         (0x213) /* Set WEP key 2*/
#endif
#ifndef EIOCSWEPKEY3
 #define EIOCSWEPKEY3         (0x214) /* Set WEP key 3*/
#endif
#ifndef EIOCSWEPDEFAULTKEY
 #define EIOCSWEPDEFAULTKEY   (0x215) /* Set WEP key 3*/
#endif
#ifndef EIOCSAUTHCALLBACK
 #define EIOCSAUTHCALLBACK    (0x24B) /* Register authentication callback */
#endif
#ifndef EIOCS802DOT1XMODE
 #define EIOCS802DOT1XMODE    (0x24C) /* Set 802.1x mode */
#endif
#ifndef EIOCG802DOT1XMODE
 #define EIOCG802DOT1XMODE    (0x24D) /* Get 802.1x mode status */
#endif
#ifndef EIOCGCONNECTEDBSSID
 #define EIOCGCONNECTEDBSSID  (0x220) /* Get BSSID */
#endif
#ifndef EIOCSAUTHCALLBACK  
 #define EIOCSAUTHCALLBACK    (0x24B) /* Get BSSID */
#endif

/*
*                      Public prototypes 
*/

/* Initialization functions */
END_OBJ * dot11EndLoad(char * initString, void * pBSP);

STATUS dot11HddInit(DOT11_FW * pDot11);

STATUS dot11DpeInit(DOT11_FW * pDot11);

STATUS dot11SmeInit(DOT11_FW * pDot11);

STATUS dot11RsnInit(DOT11_FW * pDot11);

INT32 dot11DebugLevelGet(int area);

STATUS dot11DebugLevelSet(int area, int level);

IMPORT void dot11BcopySwap(const char * src, char * dst, int length );

IMPORT INT32 sysClkRateGet();

#ifdef  __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCdot11Libh */

